<!-- 入库单编辑弹窗 -->
<template>
  <ele-drawer
    form
    size="calc(100vw - 250px)"
    :model-value="modelValue"
    @update:model-value="updateModelValue"
  >
    <template #header="{ titleClass }">
      <div class="flex-ba mr-30px">
        <div :class="titleClass">{{ isUpdate ? '编辑入库单' : '新增入库单' }}</div>
        <el-space :size="16">
          <el-button v-if="!data?.id || data?.status === 'DR'" type="" @click="save('DR')">草稿</el-button>
          <el-button type="primary" @click="save()">保存</el-button>
        </el-space>
      </div>
    </template>
    <el-form ref="formRef" :model="form" :rules="rules" label-width="auto">
      <el-row :gutter="16">
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="货主" prop="supplier_id">
            <el-select v-model="form.supplier_id" placeholder="请选择货主" clearable>
              <el-option v-for="item in supplierList" :key="item.id" :value="item.id" :label="item.name" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :md="6" :sm="12" :xs="24">
          <el-form-item label="仓库" prop="warehouse_id">
            <el-select v-model="form.warehouse_id" :disabled="!form.supplier_id" placeholder="请选择仓库" clearable>
              <el-option v-for="item in warehouseList" :key="item.id" :value="item.id" :label="item.name" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :md="12" :sm="24" :xs="24">
          <el-form-item label="备注" prop="remark">
            <el-input v-model="form.remark" type="textarea" autosize clearable placeholder="请输入备注" />
          </el-form-item>
        </el-col>
        <el-col :xs="24">
          <el-form-item label="商品信息" prop="product">
            <div class="mb-10px">
              <el-button type="primary" icon="IconElPlus" :disabled="!form.supplier_id || !form.warehouse_id" plain @click="showProduct = true">新增商品</el-button>
            </div>
            <el-table ref="tableRef" :data="form.product" stripe border style="width: 100%">
              <el-table-column type="index" label="序" width="60" align="center" />
              <el-table-column prop="product_name" label="商品名称" align="left" min-width="150" />
              <el-table-column prop="product_code" label="商品编码" align="center" />
              <el-table-column prop="warehouse_stock" label="仓库库存" align="center" />
              <el-table-column prop="unit" label="主单位" align="center" />
              <el-table-column prop="num" label="商品数量" align="center" :width="Math.max(...form.product.map(v => v.unit_list?.length), 1) * 150">
                <template #default="{ row, $index }">
                  <div class="flex-a">
                    <el-space>
                      <el-form-item v-for="(item, i) in row.unit_list" :key="i" :label-width="0" :prop="`product[${$index}].unit_list[${i}].num`" :required="row.unit_list.every(v => !Number(v.num))">
                        <el-input v-model="item.num" class="w-110px!" placeholder="数量" oninput="value=value.replace(/[^\d.]/g, '').replace(/^\D*([0-9]\d*\.?\d{0,2})?.*$/,'$1')">
                          <template #suffix><span class="text-#333!">{{ item.unit }}</span></template>
                        </el-input>
                      </el-form-item>
                    </el-space>
                    <div v-if="row.unit_list?.length > 1" class="flex-shrink-0 min-w-60px ml-4px text-left">
                      = {{ getTotal(row.unit_list) }}{{ row.unit }}
                    </div>
                  </div>
                </template>
              </el-table-column>
              <el-table-column prop="location" label="库位" align="center" :width="200">
                <template #default="{ row, $index }">
                  <el-form-item
                    :label-width="0"
                    :prop="`product[${$index}].location_id`"
                    required
                  >
                    <el-cascader
                      v-model="row.location_id"
                      :options="locationTree"
                      filterable
                      clearable
                      placeholder="请选择库位"
                      :show-all-levels="false"
                      placement="left"
                      :props="{ value: 'id', label: 'name', expandTrigger: 'hover', emitPath: false }"
                    />
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column
                prop="price"
                label="价格"
                align="center"
                :min-width="100"
              >
                <template #default="{ row, $index }">
                  <el-form-item
                    :label-width="0"
                    :prop="`product[${$index}].price`"
                    required
                  >
                    <el-input
                      v-model="row.price"
                      placeholder="价格"
                      oninput="value=value.replace(/[^\d.]/g, '').replace(/^\D*([0-9]\d*\.?\d{0,2})?.*$/,'$1')"
                    />
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="100" align="center">
                <template #default="{ $index }">
                  <el-link type="danger" @click="removeProduct($index)">删除</el-link>
                </template>
              </el-table-column>
            </el-table>
          </el-form-item>
        </el-col>
      </el-row>

      <SelectProduct v-model="showProduct" :selecteds="form.product" :where="{ is_location: 1, supplier_id: form.supplier_id, warehouse_id: form.warehouse_id }" @done="selectProduct" />
    </el-form>
  </ele-drawer>
</template>

<script setup>
import { listBanWarehouse, listWlList } from '@/api/common'
import SelectProduct from '@/components/Common/SelectProduct/index.vue'
import { toTree } from 'ele-admin-plus/es'

const props = defineProps({
  /** 弹窗是否打开 */
  modelValue: Boolean,
  /** 修改回显的数据 */
  data: Object,

  supplierList: Array,
})

const emit = defineEmits(['done', 'update:modelValue'])

const warehouseList = ref([])

const showProduct = ref(false)

const locationTree = ref([])
const locationList = ref([])

/** 是否是修改 */
const isUpdate = ref(false)

/** 提交状态 */
const loading = ref(false)

/** 表单实例 */
const formRef = ref(null)

const tableRef = ref(null)

/** 表单数据 */
const [form, resetFields, assignFields] = utils.useFormData({
  id: undefined,
  supplier_id: '',
  warehouse_id: '',
  remark: '',
  product: [],
})

/** 表单验证规则 */
const rules = reactive({
  supplier_id: [
    {
      required: true,
      message: '请选择货主',
      trigger: 'change',
    },
  ],
  warehouse_id: [
    {
      required: true,
      message: '请选择仓库',
      trigger: 'change',
    },
  ],
  product: [
    {
      required: true,
      message: '请选择商品',
      type: 'Array',
      trigger: 'change',
    },
  ],
})

function getLocList() {
  listWlList(form.warehouse_id).then((res) => {
    locationList.value = res.data
    locationTree.value = toTree({
      data: res.data,
      idField: 'id',
      parentIdField: 'pid',
    })
  })
}

/** 保存编辑 */
function save(status = undefined) {
  formRef.value?.validate?.((valid) => {
    if (!valid)
      return

    loading.value = true
    const product = form.product.map(v => ({
      product_id: v.product_id,
      unit: v.unit_list.map(d => ({ unit: d.unit, num: d.num })),
      location: [{
        id: v.location_id,
        name: locationList.value.find(t => t.id === v.location_id)?.name ?? '',
        num: utils.totalUnit(v.unit_list),
      }],
      price: v.price,
    }))
    const formData = {
      ...form,
      product,
      status,
    }
    utils.post('/stockEnter/edit', formData)
      .then((res) => {
        utils.message(res.msg, res.success)
        if (res.success) {
          updateModelValue(false)
          emit('done')
        }
      })
      .finally(() => {
        loading.value = false
      })
  })
}

/** 更新modelValue */
function updateModelValue(value) {
  emit('update:modelValue', value)
}

function getTotal(list) {
  return list.reduce((acc, cur) => {
    return utils.numAdd(acc, utils.numMulti(cur.num, cur.ratio))
  }, 0)
}
const defLocation = computed(() => locationList.value.filter(v => v.type === 1 && v.level === 3).sort((a, b) => b.is_def - a.is_def))

function removeProduct(index) {
  form.product.splice(index, 1)
}

function selectProduct(data) {
  data.forEach((v) => {
    v.unit_list.forEach((d) => {
      d.num = ''
    })
    if (v.location.length) {
      v.location.sort((a, b) => a.type - b.type)
    }
    else {
      v.location = defLocation.value
    }
    v.location_id = v.location[0]?.id || ''
  })
  form.product.push(...data)
  setTimeout(() => {
    tableRef.value.doLayout()
  }, 200)
}

async function getProduct() {
  const { id, warehouse_id } = props.data
  const res = await utils.get('/stockEnter/productList', { id, warehouse_id, is_all: 1 })
  res.data.forEach((v) => {
    v.unit_list = utils.cloneDeep(v.multi_unit)
    v.location_id = v.location[0]?.id ?? ''
  })
  return res.data
}

watch([() => form.supplier_id, () => form.warehouse_id], async (newVal, oldVal) => {
  if (oldVal?.[0] || oldVal?.[1]) {
    form.product = []
  }
  if (newVal[0]) { // newSupplierId
    const res = await listBanWarehouse(newVal[0])
    warehouseList.value = res.data
  }
  else {
    warehouseList.value = []
  }
  if (newVal[1]) { // newWarehouseId
    getLocList()
  }
  if (form.warehouse_id && !warehouseList.value.some(v => v.id === form.warehouse_id)) {
    form.warehouse_id = ''
  }
}, {
  immediate: true,
})

watch(
  () => props.modelValue,
  async (modelValue) => {
    if (modelValue) {
      if (props.data) {
        const product = await getProduct()
        assignFields({ ...props.data, product })
        isUpdate.value = true
      }
      else {
        isUpdate.value = false
      }
    }
    else {
      resetFields()
      formRef.value?.clearValidate?.()
    }
  },
)
</script>
